Home:ALL Converter>Dynamic nested object in PHP Laravel

Dynamic nested object in PHP Laravel

Ask Time:2020-02-24T01:21:42         Author:Mel

Json Formatter

I'm trying to nest my object depending on the parent value. I want to nest the array to its parent. Here's my example object:

    $mainObject = [
        {
            id : 1,
            title : 'title 1',
            parent: 0,
        },
        {
            id : 2,
            title : 'title 2',
            parent: 0
        },
        {
            id : 3,
            title : 'title 3',
            parent: 1
        },
        {
            id : 4,
            title : 'title 4',
            parent: 1
        },
        {
            id : 5,
            title : 'title 5',
            parent: 4
        },
        {
            id : 6,
            title : 'title 6',
            parent: 4
        }
    ];

Now, I want to produce something like this below

    $mainObject = [
        {
            id : 1,
            title : 'title 1',
            parent: 0,
            children: [
                {
                    id : 3,
                    title : 'title 3',
                    parent: 1
                },
                {
                    id : 4,
                    title : 'title 4',
                    parent: 1,
                    children: [
                        {
                            id : 5,
                            title : 'title 5',
                            parent: 4
                        },
                        {
                            id : 6,
                            title : 'title 6',
                            parent: 4
                        }
                    ]
                },
            ]
        },
        {
            id : 2,
            title : 'title 2',
            parent: 0
        },
    ];

My foreach

            $nested = [];

            foreach ($mainObject as $v) {
                if($v->parent == 0){
                    array_push($nested, $v);
                }
            }

I tried to foreach and group them but I couldn't figure out how can I achieve a 3-level-nest like the above. Please help me, I've been stock for 2 nights now.

Please note that the $mainObject is a response from my laravel app. You can share JS solution or vue.

Author:Mel,eproduced under the CC 4.0 BY-SA copyright license with a link to the original source and this disclaimer.
Link to original article:https://stackoverflow.com/questions/60364834/dynamic-nested-object-in-php-laravel
Augusto Moura :

Came up with a solution that uses Laravel Collections and doesn't use recursion:\n\n$array1 = [\n (object)[\n 'id' => 1,\n 'title' => 'title 1',\n 'parent' => 0,\n ],\n (object)[\n 'id' => 2,\n 'title' => 'title 2',\n 'parent' => 0\n ],\n (object)[\n 'id' => 3,\n 'title' => 'title 3',\n 'parent' => 1\n ],\n (object)[\n 'id' => 4,\n 'title' => 'title 4',\n 'parent' => 1\n ],\n (object)[\n 'id' => 5,\n 'title' => 'title 5',\n 'parent' => 4\n ],\n (object)[\n 'id' => 6,\n 'title' => 'title 6',\n 'parent' => 4\n ]\n];\n\n//PHP < 7.4\nfunction nestArrayByParent($array){\n $collection = Illuminate\\Support\\Collection::wrap($array);\n\n //for each array element, by reference\n foreach($collection as &$obj){\n if(!property_exists($obj, 'parent') || $obj->parent == 0) //parent is 0 or doesn't have parent att.\n continue; //ignore.\n $parentKey = $collection->search(function($item) use($obj){\n return $item->id == $obj->parent;\n });\n $parent =& $collection[$parentKey]; //parent to which we must add $obj (by reference)\n\n if(!property_exists($parent, 'children') || !$parent->children)\n $parent->children = collect([]); //initialize children att if doesn't have it\n $parent->children->push($obj); //add $obj to its parent.\n }\n\n return $collection->filter(function($obj){\n //keep only items from the top level.\n return !property_exists($obj, 'parent') || $obj->parent == 0; \n });\n}\n\n//PHP >= 7.4, with arrow functions\nfunction nestArrayByParent_7_4($array){\n $collection = Illuminate\\Support\\Collection::wrap($array);\n\n //for each array element, by reference\n foreach($collection as &$obj){\n if(!property_exists($obj, 'parent') || $obj->parent == 0) //parent is 0 or doesn't have parent att.\n continue; //ignore.\n $parentKey = $collection->search(fn($item) => $item->id == $obj->parent);\n $parent =& $collection[$parentKey]; //parent to which we must add $obj (by reference)\n\n if(!property_exists($parent, 'children') || !$parent->children)\n $parent->children = collect([]); //initialize children att if doesn't have it\n $parent->children->push($obj); //add $obj to its parent.\n }\n\n //keep only items from the top level.\n return $collection->filter(fn($obj) => !property_exists($obj, 'parent') || $obj->parent == 0); \n}\n\n//\n\ndd(nestArrayByParent($array1));\n",
2020-02-24T04:59:43
yy